package cn.iocoder.yudao.module.member.alliance.service;

import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.business.audit.enums.AuditStatusEnum;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.business.eligibility.enums.EligibilityCheckStepEnum;
import cn.iocoder.yudao.framework.business.eligibility.pojo.vo.EligibilityApplyCheckVO;
import cn.iocoder.yudao.framework.business.eligibility.service.EligibilityApplyBaseService;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.constant.ErrorCodeConstants;
import cn.iocoder.yudao.module.api.infrastructure.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.api.infrastructure.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.api.member.alliance.enums.CloudAllianceNotifySceneEnum;
import cn.iocoder.yudao.module.api.member.alliance.enums.CloudAllianceTypeEnum;
import cn.iocoder.yudao.module.api.member.alliance.vo.CloudAllianceApplyVO;
import cn.iocoder.yudao.module.api.member.user.MemberUserApi;
import cn.iocoder.yudao.module.api.shop.info.ShopInfoApi;
import cn.iocoder.yudao.module.api.shop.info.dto.ShopInfoDTO;
import cn.iocoder.yudao.module.member.alliance.dal.dataobject.CloudAllianceApplyDO;
import cn.iocoder.yudao.module.member.alliance.dal.mysql.CloudAllianceApplyMapper;
import cn.iocoder.yudao.module.member.alliance.vo.AppCloudAllianceApplySaveDTO;
import cn.iocoder.yudao.module.member.alliance.vo.CloudAllianceApplyQueryDTO;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;

/**
 * 云盟商信息 Service 实现类
 *
 * @author 山野羡民（1032694760@qq.com）
 */
@Service
@Validated
@Slf4j
public class CloudAllianceApplyServiceImpl extends EligibilityApplyBaseService<CloudAllianceApplyDO, CloudAllianceApplyVO, AppCloudAllianceApplySaveDTO, CloudAllianceApplyQueryDTO> implements CloudAllianceApplyService {
    @Resource
    private CloudAllianceApplyMapper cloudAllianceApplyMapper;

    @Resource
    private CloudAlliancePackageService cloudAlliancePackageService;
    @Resource
    private AppCloudAllianceUserService appCloudAllianceUserService;

    @Resource
    private NotifyMessageSendApi notifyMessageSendApi;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private ShopInfoApi shopInfoApi;

    @Override
    protected CloudAllianceApplyMapper getInjectedMapper() {
        return cloudAllianceApplyMapper;
    }

    @Nonnull
    @Override
    protected CoreQueryWrapper<CloudAllianceApplyDO> buildQueryWrapper(CloudAllianceApplyQueryDTO param) {
        CoreQueryWrapper<CloudAllianceApplyDO> wrapper = super.buildQueryWrapper(param);
        if (param == null) {
            return wrapper;
        }
        wrapper.likeIfPresent("contact_name", param.getContactName());
        wrapper.likeIfPresent("contact_mobile", param.getContactMobile());
        wrapper.eqIfPresent("audit_status", param.getAuditStatus());
        wrapper.eqIfPresent("type", param.getType());
        return wrapper;
    }

    @Override
    public void validateCanCreate(Long userId, @Nullable Integer userType, AppCloudAllianceApplySaveDTO reqVO) {
        super.validateCanCreate(userId, userType, reqVO);
        ShopInfoDTO shopInfoRespDTO = shopInfoApi.getShopInfoByMemberUserId(userId);
        if (shopInfoRespDTO != null) {
            Assertions.isTrue(Objects.equals(reqVO.getType(), CloudAllianceTypeEnum.MERCHANT.getValue()), "商家只能入驻成为云盟商户");
            reqVO.setShopId(shopInfoRespDTO.getId());
        }
        if (Objects.equals(reqVO.getType(), CloudAllianceTypeEnum.MERCHANT.getValue())) {
            Assertions.notNull(shopInfoRespDTO, "请先入驻成为商家后再来申请");
            reqVO.setShopId(shopInfoRespDTO.getId());
        }
    }

    @Override
    public void validateCanUpdate(Long id, AppCloudAllianceApplySaveDTO reqVO) {
        CloudAllianceApplyDO entity = validateExists(id);
        if (Objects.equals(entity.getAuditStatus(), AuditStatusEnum.PASS.getValue())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.AUDIT_PASS_CANNOT_UPDATE);
        }
        ShopInfoDTO shopInfoRespDTO = shopInfoApi.getShopInfoByMemberUserId(entity.getUserId());
        if (shopInfoRespDTO != null) {
            Assertions.isTrue(Objects.equals(reqVO.getType(), CloudAllianceTypeEnum.MERCHANT.getValue()), "商家只能入驻成为云盟商户");
            reqVO.setShopId(shopInfoRespDTO.getId());
        }
    }

    @Nonnull
    @Override
    public CloudAllianceApplyDO buildSaveInfo(AppCloudAllianceApplySaveDTO reqVO) {
        CloudAllianceApplyDO entity = BeanUtils.toBean(reqVO, CloudAllianceApplyDO.class);
        entity.setPackageId(0L);
        return entity;
    }

    @Nonnull
    @Override
    public CloudAllianceApplyVO buildApplyInfo(@Nonnull CloudAllianceApplyDO aDo) {
        CloudAllianceApplyVO memberAgencyRespVO = BeanUtils.toBean(aDo, CloudAllianceApplyVO.class);
        if (aDo.getShopId() != null && aDo.getShopId() > 0) {
            memberAgencyRespVO.setShop(shopInfoApi.getShopInfo(aDo.getShopId()));
        }
        if (aDo.getPackageId() == null) {
            memberAgencyRespVO.setPackageId(0L);
        }
        return memberAgencyRespVO;
    }

    @Override
    public EligibilityApplyCheckVO<CloudAllianceApplyVO> check(Long userId, @Nullable Integer userType) {
        EligibilityApplyCheckVO<CloudAllianceApplyVO> respVO = super.check(userId, userType);
        if (Objects.equals(respVO.getStep(), EligibilityCheckStepEnum.SUCCESS.getValue())) {
            if (respVO.getInfo().getPackageId() == null || respVO.getInfo().getPackageId() <= 0) {
                respVO.setStep(EligibilityCheckStepEnum.NEED_BUY.getValue());
                respVO.setTips("需要缴纳费用才能真正成为云盟商");
                respVO.setPackageValue(cloudAlliancePackageService.getOne(userId));
            } else {
                respVO.setPackageValue(cloudAlliancePackageService.getDetail(respVO.getInfo().getPackageId()));
            }
        }
        return respVO;
    }

    @Override
    public void onAuditAfter(boolean passed, @Nonnull CloudAllianceApplyDO aDo) {
        appCloudAllianceUserService.updateWhenAuditPassed(aDo);
        // 审核通过或不通过，发送站内信
        Map<String, Object> templateParams = MapUtil.<String, Object>builder()
                .put("typeName", aDo.getTypeName())
                .put("contactName", aDo.getContactName())
                .put("contactMobile", aDo.getContactMobile())
                .put("auditTime", aDo.getAuditTime())
                .put("auditNote", passed ? "" : aDo.getAuditNote())
                .build();
        NotifySendSingleToUserReqDTO dto = new NotifySendSingleToUserReqDTO();
        dto.setUserId(aDo.getUserId());
        if (passed) {
            dto.setTemplateCode(CloudAllianceNotifySceneEnum.APPLY_AUDIT_APPROVE.getCode());
        } else {
            dto.setTemplateCode(CloudAllianceNotifySceneEnum.APPLY_AUDIT_REJECT.getCode());
        }
        dto.setTemplateParams(templateParams);
        try {
            notifyMessageSendApi.sendSingleMessageToMember(dto);
        } catch (Exception e) {
            log.error("[member][onAuditAfter][vo({}) 给对应的用户发送站内信失败]", JsonUtils.toJsonString(dto), e);
        }
    }

    @Override
    public void updateWhenPaid(String tradeNo, Long userId, Long packageId) {
        CloudAllianceApplyDO aDo = getDetailByUserId(userId, null);
        if (aDo == null) {
            return;
        }
        aDo.setPackageId(packageId);
        getInjectedMapper().updateById(aDo);
    }

    @Override
    public PageResult<CloudAllianceApplyVO> getPage(Integer current, Integer size, @Nonnull CloudAllianceApplyQueryDTO param) {
        PageResult<CloudAllianceApplyVO> page = super.getPage(current, size, param);
        Set<Long> userIds = convertSet(page.getList(), CloudAllianceApplyVO::getUserId);
        Map<Long, UserSimpleVO> userMap = memberUserApi.getUserSimpleMap(userIds);
        Set<Long> shopIds = convertSet(page.getList(), CloudAllianceApplyVO::getShopId);
        Map<Long, ShopInfoDTO> shopMap = shopInfoApi.getShopInfoMap(shopIds);
        for (CloudAllianceApplyVO item : page.getList()) {
            item.setUser(userMap.getOrDefault(item.getUserId(), UserSimpleVO.ANONYMOUS));
            item.setShop(shopMap.getOrDefault(item.getShopId(), ShopInfoDTO.FALLBACK));
        }
        return page;
    }

}
